package com.letoo.dragon.common.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 基于 httpclient 4.5.2版本的 http工具类 暂时只提供简单get、post功能后续进行丰富
 * 
 * @author dengjie
 *
 */
public class MyHttpclientUtils {

    private static final Logger LOG = LoggerFactory.getLogger(MyHttpclientUtils.class);
    private static CloseableHttpClient httpClient;
    public static final String CHARSET = "UTF-8";

    private static void setDefaultRequestConfig() {
        RequestConfig config = RequestConfig.custom().setConnectTimeout(60000).setSocketTimeout(15000).build();
        httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
    }

    private static void setRequestConfig(int connectTimeout, int socketTimeout) {
        RequestConfig config = RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).build();
        httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build();
    }

    /**
     * HTTP Get 获取内容.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?参数之前的地址
     * @param params
     *            请求的参数
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     */
    public static String doGet(String url, Map<String, String> params, Map<String, String> headers) {
        setDefaultRequestConfig();
        return doGet(url, params, CHARSET, headers);
    }

    /**
     * HTTP Post 获取内容.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param params
     *            请求的参数
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     */
    public static String doPost(String url, Map<String, String> params, Map<String, String> headers) {
        setDefaultRequestConfig();
        return doPost(url, params, CHARSET, headers);
    }

    /**
     * HTTP Post JSON获取内容.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param json
     *            请求的JSON内容
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     */
    public static String doPostForJson(String url, String json, Map<String, String> headers) {
        setDefaultRequestConfig();
        return doPostForJson(url, json, CHARSET, headers);
    }

    /**
     * HTTP Post xml获取内容.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param xml
     *            请求的xml内容
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     */
    public static String doPostForXml(String url, String xml, Map<String, String> headers) {
        setDefaultRequestConfig();
        return doPostForXml(url, xml, CHARSET, headers);
    }

    /**
     * HTTP Get 获取内容，并且内部不处理异常.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?参数之前的地址
     * @param params
     *            请求的参数
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     * @throws Exception
     * @throws IOException
     * @throws UnsupportedEncodingException
     * @throws ParseException
     */
    public static String doGetAndThrowable(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
        setDefaultRequestConfig();
        return doGetAndThrowable(url, params, CHARSET, headers);
    }

    /**
     * HTTP Post 获取内容，并且内部不处理异常.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param params
     *            请求的参数
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     * @throws Exception
     * @throws IOException
     * @throws ClientProtocolException
     */
    public static String doPostAndThrowable(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
        setDefaultRequestConfig();
        return doPostAndThrowable(url, params, CHARSET, headers);
    }

    /**
     * HTTP Post JSON获取内容，并且内部不处理异常.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param json
     *            请求的JSON内容参数
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     * @throws Exception
     * @throws IOException
     * @throws ClientProtocolException
     */
    public static String doPostAndThrowableForJson(String url, String json, Map<String, String> headers) throws Exception {
        setDefaultRequestConfig();
        return doPostAndThrowableForJson(url, json, CHARSET, headers);
    }

    /**
     * HTTP Post xml获取内容，并且内部不处理异常.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param xml
     *            请求的xml参数
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     * @throws Exception
     * @throws IOException
     * @throws ClientProtocolException
     */
    public static String doPostAndThrowableForXml(String url, String xml, Map<String, String> headers) throws Exception {
        setDefaultRequestConfig();
        return doPostAndThrowableForXml(url, xml, CHARSET, headers);
    }

    /**
     * HTTP Get 获取内容.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?参数之前的地址
     * @param params
     *            请求的参数
     * @param connectTimeout
     *            连接时间
     * @param socketTimeout
     *            数据传输时间
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     */
    public static String doGet(String url, Map<String, String> params, int connectTimeout, int socketTimeout, Map<String, String> headers) {
        setRequestConfig(connectTimeout, socketTimeout);
        return doGet(url, params, CHARSET, headers);
    }

    /**
     * HTTP Post 获取内容.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param params
     *            请求的参数
     * @param connectTimeout
     *            连接时间
     * @param socketTimeout
     *            数据传输时间
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     */
    public static String doPost(String url, Map<String, String> params, int connectTimeout, int socketTimeout, Map<String, String> headers) {
        setRequestConfig(connectTimeout, socketTimeout);
        return doPost(url, params, CHARSET, headers);
    }

    /**
     * HTTP Post JSON获取内容.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param json
     *            请求的JSON内容
     * @param connectTimeout
     *            连接时间
     * @param socketTimeout
     *            数据传输时间
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     */
    public static String doPostForJson(String url, String json, int connectTimeout, int socketTimeout, Map<String, String> headers) {
        setRequestConfig(connectTimeout, socketTimeout);
        return doPostForJson(url, json, CHARSET, headers);
    }

    /**
     * HTTP Post xml获取内容.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param xml
     *            请求的xml内容
     * @param connectTimeout
     *            连接时间
     * @param socketTimeout
     *            数据传输时间
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     */
    public static String doPostForXml(String url, String xml, int connectTimeout, int socketTimeout, Map<String, String> headers) {
        setRequestConfig(connectTimeout, socketTimeout);
        return doPostForXml(url, xml, CHARSET, headers);
    }

    /**
     * HTTP Get 获取内容，并且内部不处理异常.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?参数之前的地址
     * @param params
     *            请求的参数
     * @param connectTimeout
     *            连接时间
     * @param socketTimeout
     *            数据传输时间
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     * @throws Exception
     * @throws IOException
     * @throws UnsupportedEncodingException
     * @throws ParseException
     */
    public static String doGetAndThrowable(String url, Map<String, String> params, int connectTimeout, int socketTimeout, Map<String, String> headers) throws Exception {
        setRequestConfig(connectTimeout, socketTimeout);
        return doGetAndThrowable(url, params, CHARSET, headers);
    }

    /**
     * HTTP Post 获取内容，并且内部不处理异常.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param params
     *            请求的参数
     * @param connectTimeout
     *            连接时间
     * @param socketTimeout
     *            数据传输时间
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     * @throws Exception
     * @throws IOException
     * @throws ClientProtocolException
     */
    public static String doPostAndThrowable(String url, Map<String, String> params, int connectTimeout, int socketTimeout, Map<String, String> headers) throws Exception {
        setRequestConfig(connectTimeout, socketTimeout);
        return doPostAndThrowable(url, params, CHARSET, headers);
    }

    /**
     * HTTP Post JSON获取内容，并且内部不处理异常.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param json
     *            请求的JSON内容参数
     * @param connectTimeout
     *            连接时间
     * @param socketTimeout
     *            数据传输时间
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     * @throws Exception
     * @throws IOException
     * @throws ClientProtocolException
     */
    public static String doPostAndThrowableForJson(String url, String json, int connectTimeout, int socketTimeout, Map<String, String> headers) throws Exception {
        setRequestConfig(connectTimeout, socketTimeout);
        return doPostAndThrowableForJson(url, json, CHARSET, headers);
    }

    /**
     * HTTP Post xml获取内容，并且内部不处理异常.默认采用UTF-8编码
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param xml
     *            请求的xml参数
     * @param connectTimeout
     *            连接时间
     * @param socketTimeout
     *            数据传输时间
     * @param headers
     *            请求的headers参数
     * @return 页面内容
     * @throws Exception
     * @throws IOException
     * @throws ClientProtocolException
     */
    public static String doPostAndThrowableForXml(String url, String xml, int connectTimeout, int socketTimeout, Map<String, String> headers) throws Exception {
        setRequestConfig(connectTimeout, socketTimeout);
        return doPostAndThrowableForXml(url, xml, CHARSET, headers);
    }

    /**
     * HTTP Get 获取内容
     * 
     * @param url
     *            请求的url地址 ?参数之前的地址
     * @param params
     *            请求的参数
     * @param charset
     *            编码格式
     * @return 页面内容
     */
    private static String doGet(String url, Map<String, String> params, String charset, Map<String, String> headers) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        try {
            if (params != null && !params.isEmpty()) {
                List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
                url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset));
            }
            HttpGet httpGet = new HttpGet(url);
            // 新增header
            if (headers != null && headers.size() != 0) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpGet.addHeader(entry.getKey(), entry.getValue());
                }
            }
            // 新增header
            CloseableHttpResponse response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpGet.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            LOG.error("", e);
        } finally {
            try {
                httpClient.close();
                httpClient = null;
            } catch (IOException e) {
                LOG.error("", e);
            }
        }
        return null;
    }

    /**
     * HTTP Post 获取内容
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param params
     *            请求的参数
     * @param charset
     *            编码格式
     * @return 页面内容
     */
    private static String doPost(String url, Map<String, String> params, String charset, Map<String, String> headers) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        try {
            List<NameValuePair> pairs = null;
            if (params != null && !params.isEmpty()) {
                pairs = new ArrayList<NameValuePair>(params.size());
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
            }
            HttpPost httpPost = new HttpPost(url);
            // 新增header
            if (headers != null && headers.size() != 0) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            // 新增header
            if (pairs != null && pairs.size() > 0) {
                httpPost.setEntity(new UrlEncodedFormEntity(pairs, charset));
            }
            CloseableHttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            LOG.error("", e);
        }
        return null;
    }

    /**
     * HTTP Post JSON获取内容
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param json
     *            请求的JSON内容
     * @param charset
     *            编码格式
     * @return 页面内容
     */
    private static String doPostForJson(String url, String json, String charset, Map<String, String> headers) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        try {
            HttpPost httpPost = new HttpPost(url);
            // 新增header
            if (headers != null && headers.size() != 0) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            // 新增header
            httpPost.addHeader("content-type", "application/json");
            if (StringUtils.isNotBlank(json)) {
                httpPost.setEntity(new StringEntity(json, charset));
            }
            CloseableHttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            LOG.error("", e);
        }
        return null;
    }

    /**
     * HTTP Post xml获取内容
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param xml
     *            请求的xml内容
     * @param charset
     *            编码格式
     * @return 页面内容
     */
    private static String doPostForXml(String url, String xml, String charset, Map<String, String> headers) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        try {
            HttpPost httpPost = new HttpPost(url);
            // 新增header
            if (headers != null && headers.size() != 0) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            // 新增header
            httpPost.addHeader("content-type", "text/xml");
            if (StringUtils.isNotBlank(xml)) {
                httpPost.setEntity(new StringEntity(xml, charset));
            }
            CloseableHttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            LOG.error("", e);
        }
        return null;
    }

    /**
     * HTTP Get 获取内容，并且内部不处理异常
     * 
     * @param url
     *            请求的url地址 ?参数之前的地址
     * @param params
     *            请求的参数
     * @param charset
     *            编码格式
     * @return 页面内容
     * @throws Exception
     */
    private static String doGetAndThrowable(String url, Map<String, String> params, String charset, Map<String, String> headers) throws Exception {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        try {
            if (params != null && !params.isEmpty()) {
                List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
                url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, charset));
            }
            HttpGet httpGet = new HttpGet(url);
            // 新增header
            if (headers != null && headers.size() != 0) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpGet.addHeader(entry.getKey(), entry.getValue());
                }
            }
            // 新增header
            CloseableHttpResponse response = httpClient.execute(httpGet);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpGet.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            LOG.error("", e);
            throw e;
        } finally {
            try {
                httpClient.close();
                httpClient = null;
            } catch (IOException e) {
                LOG.error("", e);
            }
        }
    }

    /**
     * HTTP Post 获取内容，并且内部不处理异常
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param params
     *            请求的参数
     * @param charset
     *            编码格式
     * @return 页面内容
     * @throws Exception
     */
    private static String doPostAndThrowable(String url, Map<String, String> params, String charset, Map<String, String> headers) throws Exception {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        try {
            List<NameValuePair> pairs = null;
            if (params != null && !params.isEmpty()) {
                pairs = new ArrayList<NameValuePair>(params.size());
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    String value = entry.getValue();
                    if (value != null) {
                        pairs.add(new BasicNameValuePair(entry.getKey(), value));
                    }
                }
            }
            HttpPost httpPost = new HttpPost(url);
            // 新增header
            if (headers != null && headers.size() != 0) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            // 新增header
            if (pairs != null && pairs.size() > 0) {
                httpPost.setEntity(new UrlEncodedFormEntity(pairs, charset));
            }
            CloseableHttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            LOG.error("", e);
            throw e;
        }
    }

    /**
     * HTTP Post JSON获取内容，并且内部不处理异常
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param json
     *            请求的JSON内容参数
     * @param charset
     *            编码格式
     * @return 页面内容
     * @throws Exception
     */
    private static String doPostAndThrowableForJson(String url, String json, String charset, Map<String, String> headers) throws Exception {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        try {
            HttpPost httpPost = new HttpPost(url);
            // 新增header
            if (headers != null && headers.size() != 0) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            // 新增header
            httpPost.addHeader("content-type", "application/json");
            if (StringUtils.isNotBlank(json)) {
                httpPost.setEntity(new StringEntity(json, charset));
            }
            CloseableHttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            LOG.error("", e);
            throw e;
        }
    }

    /**
     * HTTP Post xml获取内容，并且内部不处理异常
     * 
     * @param url
     *            请求的url地址 ?之前的地址
     * @param xml
     *            请求的xml参数
     * @param charset
     *            编码格式
     * @return 页面内容
     * @throws Exception
     */
    private static String doPostAndThrowableForXml(String url, String xml, String charset, Map<String, String> headers) throws Exception {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        try {
            HttpPost httpPost = new HttpPost(url);
            // 新增header
            if (headers != null && headers.size() != 0) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            // 新增header
            httpPost.addHeader("content-type", "text/xml");
            if (StringUtils.isNotBlank(xml)) {
                httpPost.setEntity(new StringEntity(xml, charset));
            }
            CloseableHttpResponse response = httpClient.execute(httpPost);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != 200) {
                httpPost.abort();
                throw new RuntimeException("HttpClient,error status code :" + statusCode);
            }
            HttpEntity entity = response.getEntity();
            String result = null;
            if (entity != null) {
                result = EntityUtils.toString(entity, "utf-8");
            }
            EntityUtils.consume(entity);
            response.close();
            return result;
        } catch (Exception e) {
            LOG.error("", e);
            throw e;
        }
    }

    public static void main(String[] args) {
        long beginTime = System.currentTimeMillis();
        for (int i = 0; i < 10; i++) {
            String getData = doGet("http://www.baidu.com/", null, null);
        }
        long endTime = System.currentTimeMillis();
        LOG.info("MyHttpclientUtils.doGetAndThrowable use time is:" + (endTime - beginTime));
        // System.out.println(getData);
        System.out.println("----------------------分割线-----------------------");
        long beginTime1 = System.currentTimeMillis();
        String postData = doGet("http://www.baidu.com/", null, null);
        long endTime1 = System.currentTimeMillis();
        LOG.info("MyHttpclientUtils.doGetAndThrowable use time is:" + (endTime1 - beginTime1));
        // System.out.println(postData);
    }

}
